#include"head.h"

int get_lis_socket( Addr& addr,int lack)
{
	int lisfd=socket(AF_INET,SOCK_STREAM,0);    //创建socket
	
	if(lisfd<=0)
		return -1;
	
	evutil_make_socket_nonblocking(lisfd);          //设置非阻塞套接字
	
	if(bind(lisfd,(sockaddr*)(addr.get_addr()),sizeof(sockaddr_in))<0)
		return -1;		
		
	if(listen(lisfd,lack)<0)	
		return -1;
	
	return lisfd;
}

void apt_func(int lisfd,short event,void *arg)
{	
	Recorder *recorder=Recorder::get_recorder();   //获得记录者
	
	event_base *base=(event_base*)arg;
	
	int fd=accept(lisfd,NULL,NULL);            //get connect fd
	if(fd<0)
	{
		recorder->dbg_rd("Accept connection failed!!");
		return;
	}
	
	evutil_make_socket_nonblocking(fd);         
	
	bufferevent *bfev=bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
	
	if(bfev==NULL)
	{
		recorder->dbg_rd("Bufferevent create failed");
		return;
	}
	bufferevent_setcb(bfev,read_func,NULL,err_func,arg);     //set defunction for read and err 
	
	bufferevent_enable(bfev,EV_READ | EV_ET | EV_PERSIST);
	
}

void err_func(bufferevent *bfev,short event,void *arg)
{
	Recorder *recorder=Recorder::get_recorder();
	if (event & BEV_EVENT_EOF)		
		recorder->run_rd("connection closed\n",bfev);
    else
		recorder->dbg_rd("have one unknow error \n");
	List::get_list()->list_erase(bfev);
	bufferevent_free(bfev);
}

void read_func(bufferevent *bfev,void *arg)
{
	Recorder *recorder=Recorder::get_recorder();
	event_base *base=(event_base *)arg;
	
	char rbuf[MAX_RBUF_SIZE]={0};
	
	bufferevent_read(bfev,rbuf,sizeof(rbuf));
	
	recorder->dbg_rd(rbuf);
	
	deal(bfev,rbuf);
}

void deal(bufferevent *bfev,const char *rbuf)
{
	Recorder *recorder=Recorder::get_recorder();
	Json::Reader reader;
	Json::Value value;
	if(reader.parse(rbuf,value))       //parse the message
	{
		int n=value["type"].asInt();
		Deal *deal=get_deal(n);   //get the really deal object
		if(deal!=NULL)
		{
			deal->deal(bfev,value);
			delete deal;
			return;
		}
	}
	else
		recorder->dbg_rd("Parse the message have some error !");
	bufferevent_write(bfev,"The message have some error",MAX_SBUF_SIZE);
}

Deal* get_deal(int n)
{
	Deal *deal=NULL;
	if(n>=MIN_MESSAGE_NUM && n<=MAX_MESSAGE_NUM)
	{
		switch(n)
		{
			case LOGIN_MESSAGE:
				deal=new Deal_login();
				break;
			case JOIN_MESSAGE:
				deal=new Deal_join();
				break;
			case SEND_ROOM:
				deal=new Deal_room();
				break;
			default:
				break;
		}
	}
	return deal;
}














